﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UIFrameWork;
using UnityEditor;
using UnityEngine;

namespace UIFrameWork
{
    public class GeneratorWindowTool : Editor
    {
        static Dictionary<string, string> methodDic = new Dictionary<string, string>();

        [MenuItem("GameObject/Farmework/UGUI/生成Window脚本(Shift+V) #V", false, 0)]
        private static void CreaterFindComponentScripts()
        {
            GameObject obj = Selection.objects.First() as GameObject;
            if (obj == null)
            {
                Debug.LogError("需要选择 GameObject");
                return;
            }

            if (Directory.Exists(GeneratorConfig.WindowGenertorPath))
            {
                Directory.CreateDirectory(GeneratorConfig.WindowGenertorPath);
            }

            // 生成脚本
            GeneratorFindComponentTool.objDataList = new List<EditorObjectData>();
            GeneratorFindComponentTool.objFindPathDic = new Dictionary<int, string>();

            List<EditorObjectData> tmp;

            if (GeneratorConfig.ParseType == ParseType.Tag)
                tmp = GeneratorFindComponentTool.PresWindowNodeDataByTag(obj.transform, obj.name);
            else
                tmp = GeneratorFindComponentTool.PresWindowNodeData(obj.transform, obj.name);

            string cs = CreateWindowCs(obj.name, tmp);
            string csPath = GeneratorConfig.WindowGenertorPath + "/" + obj.name + ".cs";
            //Debug.Log(csPath);
            UIWindowEditor.ShowWindow(cs, csPath, methodDic);
        }

        public static string CreateWindowCs(string name, List<EditorObjectData> objDatalist)
        {
            methodDic.Clear();
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("/*----------------------------------");
            sb.AppendLine(" *Title:UI自动化Window代码生成工具");
            sb.AppendLine(" *Author:SteveSimon");
            sb.AppendLine(" *Date:" + System.DateTime.Now);
            sb.AppendLine(" *Description:UI窗口表现层，右键窗口节点生成Window脚本即可");
            sb.AppendLine(" *注意*:以下脚本是自动生成的，每次更新不会覆盖，可以放心使用");
            sb.AppendLine(" *----------------------------------*/");
            sb.AppendLine();

            sb.AppendLine("using UnityEngine.UI;");
            sb.AppendLine("using UnityEngine;");
            sb.AppendLine("using UIFrameWork.UGUIPro;");
            sb.AppendLine();

            sb.AppendLine("namespace UIFrameWork");
            sb.AppendLine("{");

            sb.AppendLine("\tpublic class " + name + " : WindowBase");
            sb.AppendLine("\t{");

            // 生成字段
            if (GeneratorConfig.GeneratorType == GeneratorType.Bind)
            {
                sb.AppendLine($"\t\tpublic {name}DataComponent dataCompt;");
            }
            else
            {
                sb.AppendLine($"\t\tpublic {name}UIComponent uiCompt=new {name}UIComponent();");
            }

            // 生成生命周期函数
            sb.AppendLine("\t");
            sb.AppendLine($"\t\t#region 声明周期函数");
            sb.AppendLine($"\t\t// 调用机制与Mono Awake一致");
            sb.AppendLine("\t\tpublic override void OnAwake()");
            sb.AppendLine("\t\t{");
            if (GeneratorConfig.GeneratorType == GeneratorType.Bind)
            {
                sb.AppendLine($"\t\t\tdataCompt=gameObject.GetComponent<{name}DataComponent>();");
                sb.AppendLine($"\t\t\tdataCompt.InitComponent(this);");
            }
            else
                sb.AppendLine($"\t\t\tuiCompt.InitComponent(this);");

            sb.AppendLine("\t\t\tbase.OnAwake();");
            sb.AppendLine("\t\t}");
            //OnShow
            sb.AppendLine($"\t\t// 物体显示时执行");
            sb.AppendLine("\t\tpublic override void OnShow()");
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t\tbase.OnShow();");
            sb.AppendLine("\t\t}");
            //OnHide
            sb.AppendLine($"\t\t// 物体隐藏时执行");
            sb.AppendLine("\t\tpublic override void OnHide()");
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t\tbase.OnHide();");
            sb.AppendLine("\t\t}");

            //OnDestroy
            sb.AppendLine($"\t\t // 物体销毁时执行");
            sb.AppendLine("\t\tpublic override void OnDestroy()");
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t\tbase.OnDestroy();");
            sb.AppendLine("\t\t}");

            sb.AppendLine($"\t\t#endregion");
            sb.AppendLine();
            //API Function 
            sb.AppendLine($"\t\t#region API Function");
            sb.AppendLine($"\t\t");
            sb.AppendLine($"\t\t#endregion");
            sb.AppendLine();
            //UI组件事件生成
            sb.AppendLine($"\t\t#region UI组件事件\r\n");
            foreach (var item in objDatalist)
            {
                string type = item.fieldType;
                string methodName = "On" + item.fieldName;
                string suffix = "";
                if (type.Contains("Button"))
                {
                    suffix = "ButtonClick";
                    CreateMethod(sb, ref methodDic, methodName + suffix);
                }
                else if (type.Contains("InputField"))
                {
                    suffix = "InputChange";
                    CreateMethod(sb, ref methodDic, methodName + suffix, "string text");
                    suffix = "InputEnd";
                    CreateMethod(sb, ref methodDic, methodName + suffix, "string text");
                }
                else if (type.Contains("Toggle"))
                {
                    suffix = "ToggleChange";
                    CreateMethod(sb, ref methodDic, methodName + suffix, "bool state,Toggle toggle");
                }
            }

            sb.AppendLine($"\t\t#endregion");

            
            sb.AppendLine("\t}");
            sb.AppendLine("}");
            sb.AppendLine();
            return sb.ToString();
        }

        /// <summary>
        /// 生成UI事件方法
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="methodDic"></param>
        /// <param name="modthName"></param>
        /// <param name="param"></param>
        public static void CreateMethod(StringBuilder sb, ref Dictionary<string, string> methodDic, string methodName, string param = "")
        {
            //声明UI组件事件
            sb.AppendLine($"\t\tpublic void {methodName}({param})");
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t");
            if (methodName == "OnCloseButtonClick")
            {
                sb.AppendLine("\t\t\tHideWindow();");
            }
            sb.AppendLine("\t\t}");

            //存储UI组件事件 提供给后续新增代码使用
            StringBuilder builder = new StringBuilder();
            builder.AppendLine($"\t\tpublic void {methodName}({param})");
            builder.AppendLine("\t\t{");
            builder.AppendLine("\t\t");
            builder.AppendLine("\t\t}");
            methodDic.Add(methodName, builder.ToString());
        }
    }
}
